package com.pmcc.utils;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.http.HttpStatus;
import  org.apache.commons.httpclient.methods.RequestEntity;

import javax.imageio.ImageIO;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.InputStream;

/**
 * 缩略图
 * Created by lihaiyue on 2019/1/1
 */
public class ImageUtils {


    public static final String UPLOAD_IMAGE_URL = "https://api.weixin.qq.com/cgi-bin/media/upload";//"http://file.api.weixin.qq.com/cgi-bin/media/upload";// 上传多媒体文件
    //根据路径生成对应的缩率图
    public static void createImg(String url, int nw) {
        try {
            File fi = new File(url); //大图文件
            String[] absolutePath = fi.getAbsolutePath().split("\\.");
            String newPath = absolutePath[0] + "_narrow" + "." + absolutePath[1];
            File fo = new File(newPath); //将要转换出的小图文件
//            int nw = 200;
            /***
             *  AffineTransform 类表示 2D 仿射变换，它执行从 2D 坐标到其他 2D 坐标的线性映射，
             *  保留了线的“直线性”和“平行性”。可以使用一系列平移、缩放、翻转、旋转和剪切来构造仿射变换。
             */
            AffineTransform transform = new AffineTransform();
            BufferedImage bis = ImageIO.read(fi); //读取图片
            int w = bis.getWidth();
            int h = bis.getHeight();
            int nh = (nw * h) / w;
            double sx = (double) nw / w;
            double sy = (double) nh / h;
            transform.setToScale(sx, sy); //setToScale(double sx, double sy) 将此变换设置为缩放变换。
            System.out.println(w + " " + h);
            /*
             * AffineTransformOp类使用仿射转换来执行从源图像或 Raster 中 2D 坐标到目标图像或
             *  Raster 中 2D 坐标的线性映射。所使用的插值类型由构造方法通过
             *  一个 RenderingHints 对象或通过此类中定义的整数插值类型之一来指定。
             *  如果在构造方法中指定了 RenderingHints 对象，则使用插值提示和呈现
             *  的质量提示为此操作设置插值类型。要求进行颜色转换时，可以使用颜色
             *  呈现提示和抖动提示。 注意，务必要满足以下约束：源图像与目标图像
             *  必须不同。 对于 Raster 对象，源图像中的 band 数必须等于目标图像中的 band 数。
             */
            AffineTransformOp ato = new AffineTransformOp(transform, null);
            BufferedImage bid = new BufferedImage(nw, nh, BufferedImage.TYPE_3BYTE_BGR);
            /*
             * TYPE_3BYTE_BGR 表示一个具有 8 位 RGB 颜色分量的图像，
             * 对应于 Windows 风格的 BGR 颜色模型，具有用 3 字节存
             * 储的 Blue、Green 和 Red 三种颜色。
             */
            ato.filter(bis, bid);
            ImageIO.write(bid, "jpeg", fo);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //根据路径生成对应的缩率图
    public static void createImg(InputStream inputStream, int nw, String pathUrl, String imgType) {
        try {
            File fo = new File(pathUrl); //将要转换出的小图文件
//            int nw = 200;
            /*
             *  AffineTransform 类表示 2D 仿射变换，它执行从 2D 坐标到其他 2D 坐标的线性映射，
             *  保留了线的“直线性”和“平行性”。可以使用一系列平移、缩放、翻转、旋转和剪切来构造仿射变换。
             */
            AffineTransform transform = new AffineTransform();
            BufferedImage bis = ImageIO.read(inputStream); //读取图片
            int w = bis.getWidth();
            int h = bis.getHeight();
            int nh = (nw * h) / w;
            double sx = (double) nw / w;
            double sy = (double) nh / h;
            transform.setToScale(sx, sy); //setToScale(double sx, double sy) 将此变换设置为缩放变换。
            System.out.println(w + " " + h);
            /*
             * AffineTransformOp类使用仿射转换来执行从源图像或 Raster 中 2D 坐标到目标图像或
             *  Raster 中 2D 坐标的线性映射。所使用的插值类型由构造方法通过
             *  一个 RenderingHints 对象或通过此类中定义的整数插值类型之一来指定。
             *  如果在构造方法中指定了 RenderingHints 对象，则使用插值提示和呈现
             *  的质量提示为此操作设置插值类型。要求进行颜色转换时，可以使用颜色
             *  呈现提示和抖动提示。 注意，务必要满足以下约束：源图像与目标图像
             *  必须不同。 对于 Raster 对象，源图像中的 band 数必须等于目标图像中的 band 数。
             */
            AffineTransformOp ato = new AffineTransformOp(transform, null);
            BufferedImage bid = new BufferedImage(nw, nh, BufferedImage.TYPE_3BYTE_BGR);
            /*
             * TYPE_3BYTE_BGR 表示一个具有 8 位 RGB 颜色分量的图像，
             * 对应于 Windows 风格的 BGR 颜色模型，具有用 3 字节存
             * 储的 Blue、Green 和 Red 三种颜色。
             */
            ato.filter(bis, bid);
            ImageIO.write(bid, imgType, fo);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    /**
     * 上传多媒体文件
     *
     * @param url          访问url
     * @param access_token access_token
     * @param type         文件类型
     * @param file         文件对象
     * @return
     */
    public static String uploadImage(String url, String access_token, String type, File file) {
        System.out.println( url + access_token +file.getPath() );
        org.apache.commons.httpclient.HttpClient client = new org.apache.commons.httpclient.HttpClient();
        String uploadurl = String.format( "%s?access_token=%s&type=%s", url,
                access_token, type );
        PostMethod post = new PostMethod( uploadurl );
        post
                .setRequestHeader(
                        "User-Agent",
                        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:30.0) Gecko/20100101 Firefox/30.0" );
        post.setRequestHeader( "Host", "file.api.weixin.qq.com" );
        post.setRequestHeader( "Connection", "Keep-Alive" );
        post.setRequestHeader( "Cache-Control", "no-cache" );
        String result = null;
        System.out.println( "1111111111111111111111" );
        try {
            if (file != null && file.exists()) {
                System.out.println( "2222222222222222222" );
                FilePart filepart = new FilePart( "media", file, "image/jpeg",
                        "UTF-8" );
                Part[] parts = new Part[]{filepart};
                MultipartRequestEntity entity = new MultipartRequestEntity(
                        parts,

                        post.getParams() );
                System.out.println( "3333333333333333" );
                post.setRequestEntity( entity );
                System.out.println( "4444444444444444444" );
                int status = client.executeMethod( post );
                System.out.println( "55555555555555555555" );
                if (status == HttpStatus.SC_OK) {
                    String responseContent = post.getResponseBodyAsString();
                    JsonParser jsonparer = new JsonParser();// 初始化解析json格式的对象
                    JsonObject json = jsonparer.parse( responseContent )
                            .getAsJsonObject();
                    if (json.get( "errcode" ) == null)// {"errcode":40004,"errmsg":"invalid media type"}
                    { // 上传成功  {"type":"TYPE","media_id":"MEDIA_ID","created_at":123456789}
                        result = json.get( "media_id" ).getAsString();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            return result;
        }
    }
}
